<?php

namespace App\Http\Controllers\Frontend\V10\Users;

use App\Events\AuthStepEvent;
use App\Events\UploadIdCardEvent;
use App\Exceptions\GeneralException;
use App\Facades\SamLogFacade;
use App\Http\Requests\Frontend\V10\Users\UserFaceFailLogRequest;
use App\Http\Requests\Frontend\V10\Users\UserFaceStoreRequest;
use App\Models\User;
use App\Http\Controllers\Controller;
use App\Models\UserAuthStepEventLog;
use App\Models\UserCertOcr;
use App\Models\UserFaceFailedLog;
use App\Models\UserFaceLog;
use App\Models\UserGlobal;
use App\Models\UserLoanRequest;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;
use Illuminate\Support\Facades\Redis;

class UserFaceController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth:api');
    }

    /**
     * Description:
     * Author: Sam
     * DateTime: 2019-03-04 11:16
     * @param UserFaceStoreRequest $request
     * @return mixed
     * @throws GeneralException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function store(UserFaceStoreRequest $request)
    {
        /**
         * @var $user  User
         */

        $user = Auth::user();
        $params = $this->extractInputFromRules($request, $request->rules());
        $params['user_id'] = $user->id;
        $loan = UserLoanRequest::where(['current' => UserLoanRequest::CURRENT_NOW, 'user_id' => $user->id])->orderByDesc('id')->first();
        if (!$loan) {
            SamLogFacade::debug("用户【{$user->id}】认证人脸失败，没找到授信记录");
            return failed('用户信息异常');
        }
        DB::beginTransaction();
        try {
            $face = UserFaceLog::create($params);
            if (!empty($params['reset'])) {
                $loan->status = UserLoanRequest::STATUS_SUCCESS;
                UserLoanRequest::againNotice($loan);
            }
            if (!empty($params['hand_cert'])) {
                $ocr = UserCertOcr::find($loan->cert_ocr_id);
                $ocr->hand_cert = $params['hand_cert'];
                $ocr->save();
            }
            $loan->user_face_log_id = $face->id;
            /**
             * @var $loan UserLoanRequest
             */
            $loan->save();
            $log = [
                'uid' => $user->id,
                'step_id' => $face->id,
                'type' => UserAuthStepEventLog::STEP_FACE,
                'loan_request_id' => $loan->id,
            ];
            event(new AuthStepEvent($log));
            DB::commit();
        } catch (\Exception $exception) {
            SamLogFacade::debug($exception->getMessage());
            DB::rollBack();
            throw new GeneralException('人脸识别失败', 500);
        }
        Cache::delete("face_cache_{$user->id}");
        Cache::add("face_cache_{$user->id}", json_encode($params), 60 * 24);
        return success([]);
    }

    /**
     * Description:检测人脸识别限制次数
     * Author: Sam
     * DateTime: 2019/1/9 21:06
     * @param Request $request
     * @return mixed
     * @throws Exception
     */
    public function checkFaceLimit(Request $request)
    {
        $user = $request->user();
        $identify = UserFaceFailedLog::where(['user_id' => $user->id, 'type' => UserFaceFailedLog::TYPE_IDENTIFY_FAILED])
            ->whereDate('created_at', Carbon::now()->toDateString())
            ->count();
        $compare = UserFaceFailedLog::where(['user_id' => $user->id, 'type' => UserFaceFailedLog::TYPE_COMPARE_FAILED])
            ->whereDate('created_at', Carbon::now()->toDateString())
            ->count();

        if (!($identify < (int)config('common.face_identify_limit'))) {
            return failed('您今天人脸识别次数已达到上限');
        }
        if (!($compare < (int)config('common.face_compare_limit'))) {

            return failed('您今天人脸识别次数已达到上限');
        }
        return success([]);
    }

    /**
     * Description:判断用户24小时内有没有成功认证的人脸识别
     * Author: Sam
     * DateTime: 2019-02-27 13:25
     * @param Request $request
     * @return mixed
     */
    public function checkSuccess(Request $request)
    {
        $user = $request->user();
        $res = Cache::get("face_cache_{$user->id}");
        $return = $res ? true : false;
        return success($return);
    }

    /**
     * Description:记录用户人脸识别失败
     * Author: Sam
     * DateTime: 2019-02-27 13:56
     * @param UserFaceFailLogRequest $request
     * @return mixed
     */
    public function failedLog(UserFaceFailLogRequest $request)
    {
        $user = $request->user();
        $type = $request->get('type');

        SamLogFacade::debug("用户【{$user->id}】认证人脸失败，类型【{$type}】");
        try {
            UserFaceFailedLog::create(['user_id' => $user->id, 'type' => $type]);
        } catch (\Exception $exception) {
            return success($exception->getMessage());
        }

        if ($type == UserFaceFailedLog::TYPE_IDENTIFY_FAILED) {
            return success([]);
        }
        SamLogFacade::debug("用户【{$user->id}】2认证人脸失败，类型【{$type}】");
        $compare = UserFaceFailedLog::where(['user_id' => $user->id, 'type' => UserFaceFailedLog::TYPE_COMPARE_FAILED])
            ->whereDate('created_at', Carbon::now()->toDateString())
            ->count();

        if (!$compare) {
            return success([]);
        }

        if ($compare == 1) {
            return success('请确保是本人真实身份认证! 您还有两次机会!');
        } else if ($compare == 2) {
            return success('请确保是本人真实身份认证! 您还有一次机会!');
        } else {
            return success('请确保是本人真实身份认证! 请明天重试!');
        }

    }

    /**
     * Description:跳过人脸识别记录数据
     * Author: Sam
     * DateTime: 2019-02-27 15:51
     * @param Request $request
     * @return mixed
     * @throws GeneralException
     */
    public function faceSkip(Request $request)
    {
        $user = $request->user();
        /**
         * @var $loan UserLoanRequest
         */
        $loan = UserLoanRequest::where(['current' => UserLoanRequest::CURRENT_NOW, 'user_id' => $user->id])->first();
        if (!$loan) {
            SamLogFacade::debug("用户【{$user->id}】认证人脸失败，没找到授信记录");
            return failed('用户信息异常');
        }
        $face = UserFaceLog::where('user_id', $user->id)->orderByDesc('created_at')->first();
        DB::beginTransaction();
        try {
            $loan->user_face_log_id = $face->id;
            $log = [
                'uid' => $user->id,
                'step_id' => $face->id,
                'type' => UserAuthStepEventLog::STEP_FACE,
                'loan_request_id' => $loan->id,
            ];
            $loan->save();
            event(new AuthStepEvent($log));
            DB::commit();
        } catch (Exception $exception) {
            DB::rollBack();
            SamLogFacade::debug('跳过人脸识别记录数据失败：' . $exception->getMessage());
            throw new GeneralException('服务器错误！');

        }
        return success([]);
    }
}
